package com.test.jvm;

import java.util.concurrent.CountDownLatch;

/**
 * Created by jl on 2019/10/16
 * 演示指令重排序
 * r1、r2可能出现（0,0）（1,0）（0,2）都属于正常
 * 出现（1,2）可能是出现指令重排序了，加上volatile修饰可以防止重排序
 * 防止重排序的原理是通过加入内存屏障，读读、读写以及写写屏障都是空操作
 * 只有写读屏障会被替换为具体指令，该指令会刷新cpu缓存
 */
public class MemoryReorder {
    private static int a = 0;
    private static int b = 0;

    private static int r1;

    private static int r2;

    private static void method1() {
        r2 = a;
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        b = 1;
    }

    private static void method2() {
        r1 = b;
        a = 2;
    }

    public static void main(String[] args) {
        CountDownLatch countDownLatchStart = new CountDownLatch(1);
        CountDownLatch countDownLatchStop = new CountDownLatch(2);

        new Thread(() -> {
            try {
                countDownLatchStart.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            method1();
            countDownLatchStop.countDown();
        }).start();

        new Thread(() -> {
            try {
                countDownLatchStart.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            method2();
            countDownLatchStop.countDown();
        }).start();

        countDownLatchStart.countDown();

        while (countDownLatchStop.getCount() > 0) {
            System.out.println("waiting...");
        }
        System.out.println("r1=" + r1);
        System.out.println("r2=" + r2);
    }
}
